
package org.vasil.jouikov.service

import org.vasil.jouikov.schema.Item

class XmlService {

    def getItems = { text ->

        def xml = parseXml(text)
        def items = parseItems(xml)

        return items
    }

    def parseXml = { text ->

        try {
            return new XmlSlurper().parseText(text)
        }
        catch(error) {
            println "XmlService:parseXml:$error"
        }
    }

    def parseItems = { root ->

        if(root.name() != 'items') return [:]

        def items = []
        root.item.each { entry ->

            try {
                items << parse(entry)
            }
            catch(error) {
                items << new Item('action': 'error', 'error': error)
            }
        }
        return items
    }

    def parse = { entry ->

        try {
            def sku = getString(entry.@accwareid)

            def item = new Item(
                'sku'               : sku,
                'action'            : getString(entry.@action),
                'name': [
                    'title'         : getString(entry.itemname)
                ],
                'keywords'          : getString(),

                'node' : [
                    'nodeid'        : getString(entry.category.parentid),
                    'name'          : getString(entry.category.parentname),
                    'active'        : getBoolean('1')
                ],
                'nodes' : [
                    'nodeid'        : getString(entry.category.categoryid),
                    'name'          : getString(entry.category.catname),
                    'active'        : getBoolean('1'),
                    'preference': [
                        'name1'     : getString(entry.category.prefname1),
                        'name2'     : getString(entry.category.prefname2),
                        'name3'     : getString(entry.category.prefname3),
                        'name4'     : getString(entry.category.prefname4),
                        'name5'     : getString(entry.category.prefname5)
                    ]
                ],
                'manufact': [
                    'name'          : getString(entry.mfrname),
                    'number'        : getString(entry.mfrnumber),
                    'link'          : getString(entry.mfrlink)
                ],
                'packages': [
                    'include'       : getString(entry.packinclude),
                    'comment'       : getString(entry.packcomment)
                ],
                'vendor': [
                    'alias'         : getString(entry.vendor.alias),
                    'name'          : getString(entry.vendor.name)
                ],
                'price': [
                    'cost'          : getDouble(entry.costprice),
                    'sell'          : getDouble(entry.sellprice),
                    'hot'           : getDouble(entry.reslprice),
                    'drop'          : getDouble(),
                    'backup'        : getDouble()
                ],
                'quantity': [
                    'qty'           : getInteger(entry.qty),
                    'reserv'        : getInteger(),
                    'selling'       : getInteger(),
                    'stock'         : getBoolean(entry.stock)
                ],
                'reseller': [
                    'price1'        : getDouble(entry.reslprice1),
                    'price2'        : getDouble(entry.reslprice2),
                    'price3'        : getDouble(entry.reslprice3),
                    'qty2'          : getInteger(entry.reslqty2),
                    'qty3'          : getInteger(entry.reslqty3)
                ],
                'preference': [
                    'pos1'          : getString(entry.pref1),
                    'pos2'          : getString(entry.pref2),
                    'pos3'          : getString(entry.pref3),
                    'pos4'          : getString(entry.pref4),
                    'pos5'          : getString(entry.pref5)
                ],
                'advert': [
                    'name'          : getString(entry.advert.name),
                    'keywords'      : getString(entry.keywords),
                    'mfrname'       : getString(entry.advmfrname),
                    'mfrnumber'     : getString(entry.advmfrnumber),
                    'price'         : getBoolean(entry.advert.price),
                    'cnet'          : getBoolean(entry.advert.cnet),
                    'grabber'       : getBoolean(entry.advert.grabber),
                    'bizrate'       : getBoolean(entry.advert.bizrate),
                    'nextag'        : getBoolean(entry.advert.nextag),
                    'shopping'      : getBoolean(entry.advert.shopping),
                    'powersource'   : getBoolean(entry.advert.powersource),
                    'froogle'       : getBoolean(entry.advert.froogle),
                    'cj'            : getBoolean(entry.banner.cj),
                    'gadgetpage'    : getBoolean(entry.banner.gadgetpage),
                    'upccode'       : getString(entry.upccode),
                    'lot'           : getBoolean(entry.lot),
                    'ebay'          : getBoolean(entry.banner.ebay),
                    'drone'         : getBoolean(entry.drone)
                ],
                'banner': [
                    'special'       : getBoolean(entry.banner.special),
                    'closeout'      : getBoolean(entry.banner.closeout),
                    'comingsoon'    : getBoolean(entry.banner.comingsoon),
                    'bestprice'     : getBoolean(entry.banner.bestprice),
                    'firstpage'     : getBoolean(entry.banner.firstpage),
                    'categorypage'  : getBoolean(entry.banner.categorypage)
                ],
                'warranty': [
                    'mask'          : getInteger(entry.wtymask),
                    'price1'        : getDouble(entry.wtyprice1),
                    'price2'        : getDouble(entry.wtyprice2),
                    'price3'        : getDouble(entry.wtyprice3)
                ],
                'google': [
                    'group'         : getString(entry.googlegroup),
                    'action'        : getString(),
                    'update'        : getString(),
                    'expdate'       : getString(),
                    'answer'        : getString(),
                    'send'          : getBoolean()
                ],
                'coupon': [
//                    [
//                    'code'          : getString(''),
//                    'percent'       : getDouble('0'),
//                    'price'         : getDouble('0'),
//                    'used'          : getInteger('0'),
//                    'enddate'       : getString('')
//                    ]
                ],
                'images': [ // images from bookmaker
                    'url0'          : getString(entry.images.url0),
                    'url1'          : getString(entry.images.url1),
                    'url2'          : getString(entry.images.url2),
                    'url3'          : getString(entry.images.url3)
                ],
                'stockdate'         : getString(entry.stockdate),
                'weight'            : getDouble(entry.weight)
            )

            getEtilize(item)

            return item
        }
        catch(error) {
            return new Item('action': 'error', 'error': error)
        }
    }

    def getEtilize = { item ->

        def text = loadDescription(item.sku)

        def xml = parseDescription(text)
        
        fillDescription(xml, item)
    }

    def loadDescription = { sku ->

        try {
            def conn = "http://10.0.1.93/EditorXML/EtilizeXML.ashx?OPR=10&SKUBM=${sku}".toURL().openConnection()

            if(conn.responseCode == 200 || conn.responseCode == 201) {
                return conn.content.text
            }
            println "XmlService:loadDescription: ${conn.responseCode} : ${conn.responseMessage}"
        }
        catch(error) {
            println "XmlService:loadDescription: $error"
        }
    }

    def parseDescription = { text ->

        if(!text) return ''
        try {
            return new XmlSlurper().parseText(text)
        }
        catch(error) {
            println "XmlService:parseDescription: $error"
        }
    }

    def fillDescription = { root, item ->

        try {
            if('EMPTY' == root.D.text()) {
                return [:]
            }

            def map = [
                'etilid' : getLong(root.@PRODETID),
                'namea'  : getString(root.NAMEA),
                'nameb'  : getString(root.NAMEB),
                'minfo'  : getString(root.MINFO),
                'psiml'  : getString(root.PSIML.D),
                'paccl'  : getString(root.PACCL.D)
            ]
            item.keywords = getString(root.PKEYWRD)
                                                                  
            def spec = [:], mspec
            root.MSPEC.S.M.each { m ->
                spec[getString(m.L)] = getString(m.D)
            }
            map << ['mspec': spec]

            spec = [:]
            root.ESPEC.S.each { s ->
                mspec = [:]
                s.M.each { m ->
                    mspec[getString(m.L)] = getString(m.D)
                }
                spec[getString(s.T)] = mspec
            }
            map << ['espec': spec]

            spec = [:]
            root.SATTR.D.each { d ->
                spec[getString(d.@ATTR)] = getString(d)
            }
            map << ['sattr': spec]

            def images = [:]
            root.IMG.D.each { d ->
                switch(getString(d.@TPIMG)) {
                    case '300':
                        images['0'] = getString(d)
                        break
                    case 'Front':
                        images['front'] = getString(d)
                        break
                    case 'Right':
                        images['right'] = getString(d)
                        break
                    case 'Left':
                        images['left'] = getString(d)
                        break
                    case 'Rear':
                        images['rear'] = getString(d)
                        break
                    case 'Top':
                        images['top'] = getString(d)
                        break
                    case 'Bottom':
                        images['bottom'] = getString(d)
                        break
                    //case 'Manufacturer-Brochure':
                    //    image.pdf['brochure'] = d.text()
                    //    break
                    //case 'User-Manual':
                    //    image.pdf['manual'] = d.text()
                    //    break
                }
            }

            // get images from bookmaker
            if(!images.front && !item.images.url1.isEmpty()) {
                images.front = item.images.url1
            }
            if(!images.right && !item.images.url2.isEmpty()) {
                images.right = item.images.url2
            }
            if(!images.left && !item.images.url3.isEmpty()) {
                images.left = item.images.url3
            }

            // set front image
            if(!images['0'] && !item.images.url0.isEmpty()) {
                images['0'] = item.images.url0
            }
            else if(!images['0'] && images.front) {
                images['0'] = images.front
            }
            else if(!images['0'] && images.right) {
                images['0'] = images.right
            }
            else if(!images['0'] && images.left) {
                images['0'] = images.left
            }
            // default from category
            else if(!images['0']) {
                images['0'] = "http://10.0.2.18/defcat/${item.node.nodeid}.jpg"
            }

            def image = new ImageService('sku': item.sku)
            // store side image
            item.images = image.getMap(images)

            // store etilize
            item.etilize << map
        }
        catch(error) {
            println "XmlService:fillDescription: $error"
        }
    }

    static def getBoolean = { str ->
        if(str == null) return false
	return (str.toString() == '1' || str.toString() == 'Y') ? true : false
    }

    static def getString = { str ->
        if(str == null) return ""
	return str.toString().trim()
    }

    static def getInteger = { str ->
        if(str == null) return 0
        try {
            return Integer.parseInt(str.toString())
        }
        catch(e) {
            return 0
        }
    }

    static def getLong = { str ->
        try {
            return Long.parseLong(str.toString())
        }
        catch(e) {
            return 0L
        }
    }

    static def getDouble = { str ->
        try {
            return Double.parseDouble(str.toString())
        }
        catch(e) {
            return 0d
        }
    }

}

